﻿/// <reference name="MicrosoftAjax.js"/>


Type.registerNamespace("AJAXTreeViewControl");

AJAXTreeViewControl.AjaxTreeView = function(element) {
    AJAXTreeViewControl.AjaxTreeView.initializeBase(this, [element]);
    this._ajaxWebServiceMethod = "";
    this._treeContainerID = "";
    this._loadingImageUrl = "";
    this._rootNodeID = "";
}

AJAXTreeViewControl.AjaxTreeView.prototype = {
    initialize: function() {
        
        AJAXTreeViewControl.AjaxTreeView.callBaseMethod(this, 'initialize');
        
        // Need a reference to the tree instance. Probably not a beautyful way to do it, but it will have to do for now.
        treeViewInstance = this;
        
        this.prepareTree(this._treeContainerID);
        this.onLeafClick(this._rootNodeID, 'ATV_tree', false);
    },
    dispose: function() {        
        //Add custom dispose actions here
        AJAXTreeViewControl.AjaxTreeView.callBaseMethod(this, 'dispose');
    },
/*  =========================================================
    The properties
    =========================================================  */ 
    get_LoadingImageUrl : function() { 
        /// <value type="String" mayBeNull="false">
        /// The image to display during loading new nodes
        /// </value> 
        return this._loadingImageUrl ; 
    }, 

    set_LoadingImageUrl : function(value) { 
        /// <value type="String" mayBeNull="false">
        /// The image to display during loading new nodes
        /// </value> 
        this._loadingImageUrl = value; 
    }, 
    
    get_AjaxWebServiceMethod : function() { 
        /// <value type="String" mayBeNull="false">
        /// Name of the webservice and webservice method to call when loading new nodes. Do not include parenthesis
        /// </value> 
        return this._ajaxWebServiceMethod ; 
    }, 

    set_AjaxWebServiceMethod : function(value) { 
        /// <value type="String" mayBeNull="false">
        /// Name of the webservice and webservice method to call when loading new nodes. Do not include parenthesis
        /// </value> 
        this._ajaxWebServiceMethod = value; 
    }, 
    
    get_TreeContainerID : function() { 
        /// <value type="String" mayBeNull="false">
        /// The ID of the element in which to render the tree
        /// </value> 
        return this._treeContainerID ; 
    }, 

    set_TreeContainerID : function(value) {
        /// <value type="String" mayBeNull="false">
        /// The ID of the element in which to render the tree
        /// </value> 
        this._treeContainerID = value; 
    },
    
    get_RootNodeID : function() { 
        /// <value type="String" mayBeNull="false">
        /// Which node id to begin the tree with
        /// </value> 
        return this._rootNodeID ; 
    }, 

    set_RootNodeID : function(value) {
        /// <value type="String" mayBeNull="false">
        /// Which node id to begin the tree with
        /// </value> 
        this._rootNodeID = value; 
    },
    
    prepareTree : function(treeContainerId){
        /// <summary>
        /// Sets up the tree before it can be used
        /// </summary>
        /// <returns />
        var treeContainerEl = document.getElementById(treeContainerId);
        treeContainerEl.innerHTML = '<div id="cat_'+this._rootNodeID+'"></div>';
    },
    
    onLeafClick : function(nodeId, className, forceOpen) {
        /// <summary>
        /// triggered when a leaf or branch is clicked. It will either expand or collapse a branch
        /// </summary>
        /// <param name="nodeId" type="number">
        /// the id of the node which is being clicked
        /// </param>
        /// <returns />
        var li = document.getElementById('cat_'+nodeId);
            
        if(!li)
        {
            return;
        }

        // no sub cats means do not expand
        if(li.className.indexOf('ATV_bullet')!= -1)
            return;
        
        // check if the node has been expanded
        if(li.className.indexOf('ATV_opened')!= -1 && !forceOpen)
        {
            // update the LI
            li.className = 'ATV_closed';
            
            // possibly expand another node
            tree_expandNextInQueue();
            
            // possibly update the selected node
            tree_refreshSelectedNode();
            return;
        }
        
        // if the subnodes are collapsed, they might still be loaded
        if(li.getAttribute('loaded') == 'yes')
        {
            // get the sub nodes container
            li.className = 'ATV_opened';
            
            // possibly expand another node
            tree_expandNextInQueue();
            
            // possibly update the selected node
            tree_refreshSelectedNode();
            return;
        }
        
        // Possibly add an UL with temporary content
        var placeHolder = '<li><img src="'+this._loadingImageUrl+'" /></li>';
        var ul = document.getElementById('branch_'+nodeId);
        if(ul)
            ul.innerHTML = placeHolder;
        else
            li.innerHTML += '<ul id="branch_'+nodeId+'" class="'+className+'">'+placeHolder+'</ul>';
        
        // expand the clicked node to display the placeholder
        li.className = 'ATV_opened';
        
        // Send the AJAX request
        eval(treeViewInstance._ajaxWebServiceMethod + "(nodeId, tree_webserviceCallback, tree_webserviceFailure, nodeId, null)");
    },
    expandBranch : function(parentId, LI_Fragment) {
        /// <summary>
        /// expands a tree node and fills it with the supplied LI fragment
        /// </summary>
        /// <param name="parentId" type="number">
        /// the id of the node which is being expanded
        /// </param>
        /// <param name="LI_Fragment" type="string">
        /// An HTML fragment of LI-nodes to be inserted
        /// </param>
        /// <returns />
        // populate the UL with LI nodes
        var UL = document.getElementById('branch_'+parentId);
        UL.innerHTML = LI_Fragment;
        
        // update the parent node (LI)
        var parentNode = document.getElementById('cat_'+parentId);
        parentNode.setAttribute('loaded', 'yes');
        parentNode.className = 'ATV_opened';
        
        // possibly expand another node
        tree_expandNextInQueue();
        
        // possibly update the selected node
        tree_refreshSelectedNode();
    }
}
AJAXTreeViewControl.AjaxTreeView.registerClass('AJAXTreeViewControl.AjaxTreeView', Sys.UI.Control);



        var count = 0;
        var tree_nodesToExpand = new Array();
        var tree_selectedid = 0;
        var tree_selectedId;
        
        var treeViewInstance = null;
        
        function tree_leafClick(nodeId, className, forceOpen)
        {
            treeViewInstance.onLeafClick(nodeId, className, forceOpen);
        }
        
        function tree_webserviceCallback(LINodes, parentId)
        {
            treeViewInstance.expandBranch(parentId, LINodes);
        }
        
        function tree_webserviceFailure(error)
        {    
            var stackTrace = error.get_stackTrace();
            var message = error.get_message();
            var statusCode = error.get_statusCode();
            var exceptionType = error.get_exceptionType();
            var timedout = error.get_timedOut();
           
            // Display the error.    
            alert( "Stack Trace: " +  stackTrace + "<br/>" +
                "Service Error: " + message + "<br/>" +
                "Status Code: " + statusCode + "<br/>" +
                "Exception Type: " + exceptionType + "<br/>" +
                "Timedout: " + timedout);   
        }
        
        function tree_expandBranch(parentId, LI_Fragment)
        {
            treeViewInstance.expandBranch(parentId, LINodes);
        }
        
  /*    =========================================================
        tree_setSelectedNode()
        stores the Node number which should be marked as selected
        =========================================================  */
        function tree_setSelectedNode(id)
        {
            tree_selectedid = id;
        }
        
        
  /*    =========================================================
        tree_selectNode()
        verifies and updates the class names of the selected node 
        to ensure the right node is marked as selected
        =========================================================  */
        function tree_refreshSelectedNode()
        {
            var selectedLI = document.getElementById(tree_selectedId);
            
            if(!selectedLI && (tree_selectedid || tree_selectedid!=0))
                selectedLI = document.getElementById('cat_'+tree_selectedid);
            
            if(!selectedLI)
                return;
            
            // if the node marked as selected is wrong
            if(selectedLI.id.substr(4) != tree_selectedid)
            {
                // remove the ATV_selected class from the currently selected node
                selectedLI.className.replace('ATV_selected', '');
            }
            else
            {
                // ensure that the selected node has the ATV_selected class applied
                if(selectedLI.className.indexOf('ATV_selected') == -1 )
                {
                    // apply the ATV_selected class to the correct LI
                    selectedLI.className += " ATV_selected";
                }
                
                // update the selected id
                tree_selectedId = selectedLI.id;
            }
        }
        
  /*    =========================================================
        tree_setNodeExpansionQueue()
        Stores an array of nodes to open progressively.
        Use this method to "sync" the tree with the current page,
        in other words, if someone follows a direct link to a page
        you will want to open the tree accordingly. Send in the
        parent ids to be opened and the tree will expand them in
        turn until all of them are expanded.
        =========================================================  */
        function tree_setNodeExpansionQueue(ids)
        {
            tree_nodesToExpand = ids;
        }
        function tree_appendToNodeExpansionQueue(ids)
        {
            tree_nodesToExpand = tree_nodesToExpand.concat( ids );
            
        }
        
  /*    =========================================================
        tree_expandNextInQueue()
        pos the last Node in queue and expands it
        =========================================================  */
        function tree_expandNextInQueue()
        {
            if(tree_nodesToExpand.length < 1)
                return false;
            
            // get and remove the first Node number
            var id = tree_nodesToExpand.shift();
            
            // Expand the Node
            tree_leafClick(id, '', true);
        }
        
        
//  always end with this goodnight statement        
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();